package com.sg.service.biz.app.nb;

import cn.hutool.core.bean.BeanUtil;
import com.sg.common.util.CommonFunctionHelper;
import com.sg.common.util.RedisUtil;
import com.sg.dto.biz.app.req.*;
import com.sg.dto.biz.app.res.*;
import com.wicket.okrapp.common.baseinfo.BaseInfoDO;
import com.wicket.okrapp.common.baseinfo.BaseInfoHolder;
import org.apache.skywalking.apm.toolkit.trace.Tag;
import org.apache.skywalking.apm.toolkit.trace.Tags;
import org.apache.skywalking.apm.toolkit.trace.Trace;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

/**
 * @author ： 手工接入方法
 * @version 1.0
 * @since 2022/5/28 15:32
 */
@Service
public class NbExecuteProgress {

    @Autowired
    private RedisUtil redisUtil;

    /**
     * code:publicFieldCache
     * name:M3业务应用公共字段推送内存
     * desc:undefined
     * gen by moon at 5/27/2023, 12:55:44 AM
     **/
    @Trace(operationName = "M3业务应用公共字段推送内存")
    @Tags({@Tag(key = "参数", value = "arg[0]"),
            @Tag(key = "返回值", value = "returnedObj")})
    public ImplementBizPublicFieldPushMemoryRespDto implementBizPublicFieldPushMemory(ImplementBizPublicFieldPushMemoryReqDto reqDto) {
        BaseInfoDO domain = new BaseInfoDO();
        if (BaseInfoHolder.contextHolder.get() != null) {
            BeanUtil.copyProperties(BaseInfoHolder.contextHolder.get().getBaseInfo(), domain);
            BaseInfoHolder.contextHolder.remove();
        }
        if (reqDto.getSpaceId() != null) {
            domain.setSpecSpaceId(reqDto.getSpaceId());
        }

        if (reqDto.getCreateInductionId() != null) {
            domain.setSpecInductionRecordId(reqDto.getCreateInductionId());
        }

        if (reqDto.getAppId() != null) {
            domain.setSpecAppId(reqDto.getAppId());
        }

        CommonFunctionHelper.setBaseInfoToLocal(domain);
        return new ImplementBizPublicFieldPushMemoryRespDto();
    }

    /**
     * code:receptionService
     * name:M3约定进度：0
     * desc:undefined
     * gen by moon at 5/27/2023, 12:56:17 AM
     **/
    @Trace(operationName = "M3约定进度：0")
    @Tags({@Tag(key = "参数", value = "arg[0]"),
            @Tag(key = "返回值", value = "returnedObj")})
    public ImplementGainInParameterFieldsRespDto implementGainInParameterFields(ImplementGainInParameterFieldsReqDto reqDto) {
        return BeanUtil.toBean(reqDto, ImplementGainInParameterFieldsRespDto.class);
    }

    /**
     * code:queryCacheProgress
     * name:M3执行查缓存进度值(特殊方法）
     * desc:undefined
     * gen by moon at 7/6/2023, 10:37:57 PM
     **/
    @Trace(operationName = "M3执行查缓存进度值(特殊方法）")
    @Tags({@Tag(key = "参数", value = "arg[0]"),
            @Tag(key = "返回值", value = "returnedObj")})
    public ImplementQueryCacheProgressRespDto implementQueryCacheProgress(ImplementQueryCacheProgressReqDto reqDto) {
        ImplementQueryCacheProgressRespDto retData = new ImplementQueryCacheProgressRespDto();
        String key = reqDto.getThemeContentId() + "_" + reqDto.getObjectId() + "_" + reqDto.getUseTypeCode();
        String keyLock = reqDto.getThemeContentId() + "_" + reqDto.getObjectId() + "_" + reqDto.getUseTypeCode();

        if (reqDto.getOperationInductionId() != null) {
            key = key + "_" + reqDto.getOperationInductionId();
            keyLock = keyLock + "_" + reqDto.getOperationInductionId();
        }

        keyLock = keyLock + "_" + "keylock";

        if (reqDto.getRedisDataObjectCatalogue() != null) {
            key = reqDto.getRedisDataObjectCatalogue() + ":" + key;
            keyLock = reqDto.getRedisDataObjectCatalogue() + ":" + keyLock;
        }

        if (!redisUtil.isExisit(key)) {
            retData.setExecuteProgressValue(0D);
            return retData;
        }
        Object o = redisUtil.get(key);
        if (o instanceof Double) {
            Double tmp = (Double) o;
            BigDecimal bd = new BigDecimal(tmp);
            bd = bd.setScale(2, BigDecimal.ROUND_DOWN);
            retData.setExecuteProgressValue(bd.doubleValue());
        } else if (o instanceof Integer) {
            Integer tmp = (Integer) o;
            retData.setExecuteProgressValue(Double.valueOf(tmp));
        }

        if (redisUtil.isExisit(keyLock)) {
            retData.setLockState("LOCKING");
        } else {
            retData.setLockState("UNLOCK");
        }

        return retData;
    }

    /**
     * code:clearCacheProgress
     * name:M3执行清除缓存进度值（特殊方法）
     * desc:undefined
     * gen by moon at 7/6/2023, 10:38:14 PM
     **/
    @Trace(operationName = "M3执行清除缓存进度值（特殊方法）")
    @Tags({@Tag(key = "参数", value = "arg[0]"),
            @Tag(key = "返回值", value = "returnedObj")})
    public ImplementClearCacheProgressRespDto implementClearCacheProgress(ImplementClearCacheProgressReqDto reqDto) {
        ImplementClearCacheProgressRespDto retData = new ImplementClearCacheProgressRespDto();
        String key = reqDto.getThemeContentId() + "_" + reqDto.getObjectId() + "_" + reqDto.getUseTypeCode();
        String keyLock = reqDto.getThemeContentId() + "_" + reqDto.getObjectId() + "_" + reqDto.getUseTypeCode();

        if (reqDto.getOperationInductionId() != null) {
            key = key + "_" + reqDto.getOperationInductionId();
            keyLock = keyLock + "_" + reqDto.getOperationInductionId();
        }

        keyLock = keyLock + "_" + "keylock";

        if (reqDto.getRedisDataObjectCatalogue() != null) {
            key = reqDto.getRedisDataObjectCatalogue() + ":" + key;
            keyLock = reqDto.getRedisDataObjectCatalogue() + ":" + keyLock;
        }
        redisUtil.delete(key);
        redisUtil.releaseLock(keyLock, keyLock);
        return retData;
    }

    /**
     * code:updateCacheProgress
     * name:M3执行更新缓存进度值
     * desc:undefined
     * gen by moon at 7/7/2023, 2:16:56 PM
     **/
    @Trace(operationName = "M3执行更新缓存进度值")
    @Tags({@Tag(key = "参数", value = "arg[0]"),
            @Tag(key = "返回值", value = "returnedObj")})
    public ImplementUpdateCacheProgressRespDto implementUpdateCacheProgress(ImplementUpdateCacheProgressReqDto reqDto) {
        ImplementUpdateCacheProgressRespDto retData = new ImplementUpdateCacheProgressRespDto();
        String key = reqDto.getThemeContentId() + "_" + reqDto.getObjectId() + "_" + reqDto.getUseTypeCode();
        String keyLock = reqDto.getThemeContentId() + "_" + reqDto.getObjectId() + "_" + reqDto.getUseTypeCode();

        if (reqDto.getOperationInductionId() != null) {
            key = key + "_" + reqDto.getOperationInductionId();
            keyLock = keyLock + "_" + reqDto.getOperationInductionId();
        }

        keyLock = keyLock + "_" + "keylock";

        if (reqDto.getRedisDataObjectCatalogue() != null) {
            key = reqDto.getRedisDataObjectCatalogue() + ":" + key;
            keyLock = reqDto.getRedisDataObjectCatalogue() + ":" + keyLock;
        }
        if (reqDto.getExecuteProgressValue().doubleValue() == 0D) {
            redisUtil.setDouble(key, 0D);
            if (reqDto.getDuration() != null) {
                redisUtil.expire(key, reqDto.getDuration());
            } else {
                redisUtil.expire(key, 3600 * 12);
            }

            boolean lock = false;
            if (reqDto.getDuration() != null) {
                lock = redisUtil.getLock(keyLock, keyLock, reqDto.getDuration());
            } else {
                lock = redisUtil.getLock(keyLock, keyLock, 3600 * 12);
            }

            if (lock) {
                if (!CommonFunctionHelper.checkBaseInfo()) {
                    CommonFunctionHelper.setBaseInfoToLocal(new BaseInfoDO());
                }
                CommonFunctionHelper.getBaseInfoFromLocal().getLockList().add(keyLock);
                retData.setTureOrFalse("TRUE");
            } else {
                retData.setTureOrFalse("FALSE");
            }


        } else if (reqDto.getExecuteProgressValue().doubleValue() == 100D) {
            redisUtil.releaseLock(keyLock, keyLock);
        } else {
            redisUtil.increase(key, reqDto.getExecuteProgressValue());
        }
        return retData;
    }
    //手工接入方法
}
